package com.scs.application.core.global;

import com.scs.application.core.utils.IPUtils;
import com.scs.application.core.utils.SpringHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.stream.StreamSupport;

/**
 * @Description: 全局参数
 */
@Slf4j
@Service
public class GlobalParamService implements InitializingBean {

    @Autowired
    private Environment env;


    @Autowired
    private CacheManager cacheManager;

    private final String GLOBAL_CACHE = "properties";

    private String appname;

    @Override
    public void afterPropertiesSet() throws Exception {

        this.appname = env.getProperty("spring.application.name", "default");

        /**
         * 从环境变量中加载配置参数
         */
        MutablePropertySources propSrcs = ((AbstractEnvironment) env).getPropertySources();
        StreamSupport.stream(propSrcs.spliterator(), false)
                .filter(ps -> ps instanceof OriginTrackedMapPropertySource)
                .map(ps -> ((EnumerablePropertySource) ps).getPropertyNames())
                .flatMap(Arrays::<String>stream)
                .forEach(propName -> this.put(propName, env.getProperty(propName)));
        log.info(StringUtils.repeat(">", 10) + " The current application properties is loaded.");
    }

    /**
     * 加入到全局配置
     *
     * @param key
     * @param value
     */
    public void putGlobal(String key, String value) {
        cacheManager.getCache(GLOBAL_CACHE).put(key, value);
    }

    /**
     * 当前APP的配置
     *
     * @param key
     * @param value
     */
    public void put(String key, String value) {
        cacheManager.getCache(GLOBAL_CACHE).put(key, value);
    }

    /**
     * 默认从全局参数中获取。如果没找到，则从当前APP配置中获取参数信息
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public String getProperty(String key, String defaultValue) {
        Cache.ValueWrapper wrapper = cacheManager.getCache(GLOBAL_CACHE).get(key);
        if (wrapper != null) {
            return StringUtils.defaultIfBlank((String) wrapper.get(), defaultValue);
        }
        return defaultValue;
    }

    public String getProperty(String key) {
        return getProperty(key, null);
    }


    public boolean getBoolean(String key, boolean defaultValue) {
        String value = getProperty(key);
        return StringUtils.isBlank(value) ? defaultValue : Boolean.parseBoolean(value);
    }

    public boolean getBoolean(String key) {
        return getBoolean(key, false);
    }

    public String getDomain() {
        return getProperty("project.domain", IPUtils.getLocalIp());
    }

    public String getDefaultPassword() {
        return getProperty("project.defaultPassword", "123456");
    }

    public long getLong(String key, long defaultValue) {
        String value = getProperty(key);
        return StringUtils.isBlank(value) ? defaultValue : Long.parseLong(value);
    }

    /**
     * 清楚当前项目的配置
     */
    public void clear() {
        log.info(StringUtils.repeat(">", 10) + " Prepare clear current application properties cache.");
        cacheManager.getCache(GLOBAL_CACHE).clear();
        log.info(StringUtils.repeat(">", 10) + " Clear current application properties cache succeed.");

    }

    /**
     * 清除所有的项目配置信息
     */
    public void clearAll() {
        log.info(StringUtils.repeat(">", 10) + " Prepare clear all properties cache.");

        Collection<String> cacheNames = cacheManager.getCacheNames();
        for (String cacheName : cacheNames) {
            if (cacheName.startsWith(GLOBAL_CACHE)) {
                cacheManager.getCache(cacheName).clear();
                log.info(StringUtils.repeat(">", 20) + " Clear the cache {}.", cacheName);

            }
        }
        log.info(StringUtils.repeat(">", 10) + " Clear all properties cache succeed.");
    }

    public static GlobalParamService getInstance() {
        return SpringHolder.getBean(GlobalParamService.class);
    }

    /**
     * 是 开发环境？
     * @return
     */
    public boolean isDev(){
        return this.getEnvironmen().equals("dev");
    }
    /**
     * 是 功能测试环境？
     * @return
     */
    public boolean isFat(){
        return this.getEnvironmen().equals("fat");
    }
    /**
     * 是 生产环境？
     * @return
     */
    public boolean isPro(){
        return this.getEnvironmen().equals("pro");
    }

    private String getEnvironmen(){
        return env.getProperty("spring.profiles.active", "pro");
    }
}
